package org.example.myleet.p564;

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public String nearestPalindromic(String n) {
        List<Long> candidates = generateCandidates(n);
        long origin = candidates.get(0), candidate, result = Integer.MAX_VALUE, diff = Long.MAX_VALUE, d;
        for (int i = 1; i < candidates.size(); ++i) {
            candidate = candidates.get(i);
            d = Math.abs(origin - candidate);
            if (d > 0L) {
                if (d < diff) {
                    result = candidate;
                    diff = d;
                } else if (d == diff) {
                    if (candidate < result) {
                        result = candidate;
                    }
                }
            }
        }
        return Long.toString(result);
    }

    private List<Long> generateCandidates(String n) {
        List<Long> result = new ArrayList<>(6);
        //原数字放在第一个位置
        result.add(Long.parseLong(n));
        int len = n.length();
        if (len < 2) {
            long candidate = Long.parseLong(n) - 1;
            if (candidate >= 0) {
                result.add(candidate);
            }
            candidate = candidate + 2;
            result.add(candidate);
            return result;
        }
        boolean odd = (len & 1) == 1;
        int mid = odd ? len / 2 + 1 : len / 2;
        //1) 前一半字符
        String leftHalf = n.substring(0, mid);
        long leftHalfLong = Long.parseLong(leftHalf);
        String reverseNewLeftHalf;
        //1.1) +1的情况
        long newLeftHalfLong = leftHalfLong + 1;
        StringBuilder newNumber = new StringBuilder();
        reverseNewLeftHalf = reverseString(Long.toString(newLeftHalfLong));
        if (odd) {
            newNumber.append(Long.toString(newLeftHalfLong), 0, leftHalf.length()).append(reverseNewLeftHalf, 1, reverseNewLeftHalf.length());
        } else {
            newNumber.append(Long.toString(newLeftHalfLong), 0, leftHalf.length()).append(reverseNewLeftHalf);
        }
        result.add(Long.parseLong(newNumber.toString()));
        //1.2) +0的情况
        newLeftHalfLong = leftHalfLong;
        newNumber = new StringBuilder();
        reverseNewLeftHalf = reverseString(Long.toString(newLeftHalfLong));
        if (odd) {
            newNumber.append(newLeftHalfLong).append(reverseNewLeftHalf, 1, reverseNewLeftHalf.length());
        } else {
            newNumber.append(newLeftHalfLong).append(reverseNewLeftHalf);
        }
        result.add(Long.parseLong(newNumber.toString()));
        //1.3) -1的情况
        newLeftHalfLong = leftHalfLong - 1;
        newNumber = new StringBuilder();
        reverseNewLeftHalf = reverseString(Long.toString(newLeftHalfLong));
        if (odd) {
            newNumber.append(newLeftHalfLong).append(reverseNewLeftHalf, 1, reverseNewLeftHalf.length());
        } else {
            newNumber.append(newLeftHalfLong).append(reverseNewLeftHalf);
        }
        result.add(Long.parseLong(newNumber.toString()));
        //2) 999...的情况
        newNumber = new StringBuilder();
        for (int i = 0; i < len - 1; ++i) {
            newNumber.append('9');
        }
        result.add(Long.parseLong(newNumber.toString()));
        //3) 10...01的情况
        newNumber = new StringBuilder();
        newNumber.append('1');
        for (int i = 0; i < len - 1; ++i) {
            newNumber.append('0');
        }
        newNumber.append('1');
        result.add(Long.parseLong(newNumber.toString()));
        return result;
    }

    private String reverseString(String s) {
        StringBuilder sb = new StringBuilder(s.length());
        char[] ca = s.toCharArray();
        int l = 0, r = s.length() - 1;
        char t;
        while (l < r) {
            t = ca[l];
            ca[l] = ca[r];
            ca[r] = t;
            ++l;
            --r;
        }
        return new String(ca);
    }
}
